#include "http_server.h"
#include <iostream>
#include <sstream>
#include <chrono>
#include <iomanip>
#include <format>
#include "../log/log.h"

HttpServer::HttpServer(const std::string& address, unsigned short port, int threads)
    : ioc_(threads)
    , acceptor_(ioc_)
    , address_(address)
    , port_(port)
    , threads_(threads)
    , running_(false)
{
    // 设置默认处理器
    defaultHandler_ = std::bind(&HttpServer::defaultRequestHandler, this, 
                               std::placeholders::_1, std::placeholders::_2);
    addRoute("GET", "/test", std::bind(&HttpServer::onGetTest, this,  std::placeholders::_1, std::placeholders::_2));
}

HttpServer::~HttpServer() {
    stop();
}

void HttpServer::run() {
    try {
        // 绑定地址和端口
        beast::error_code ec;
        acceptor_.open(tcp::v4(), ec);
        if (ec) {
            throw std::runtime_error("Failed to open acceptor: " + ec.message());
        }
        
        acceptor_.set_option(net::socket_base::reuse_address(true), ec);
        if (ec) {
            throw std::runtime_error("Failed to set reuse address: " + ec.message());
        }
        
        acceptor_.bind({net::ip::make_address(address_), port_}, ec);
        if (ec) {
            throw std::runtime_error("Failed to bind: " + ec.message());
        }
        
        acceptor_.listen(net::socket_base::max_listen_connections, ec);
        if (ec) {
            throw std::runtime_error("Failed to listen: " + ec.message());
        }
        
        std::cout << "HTTP Server Start: " << address_ << ":" << port_ << std::endl;
        
        running_ = true;
        doAccept();
        
        // 运行IO上下文
        std::vector<std::thread> thread_pool;
        thread_pool.reserve(threads_ - 1);
        
        for (int i = 0; i < threads_ -1 ; ++i) {
            thread_pool.emplace_back([this] {
                ioc_.run();
            });
        }
        
        ioc_.run();
        
        // 等待所有线程完成
        for (auto& t : thread_pool) {
            t.join();
        }
        
    } catch (const std::exception& e) {
        std::cerr << "HTTP Server Start Failed: " << e.what() << std::endl;
    }
}

void HttpServer::stop() {
    if (running_) {
        running_ = false;
        acceptor_.close();
        ioc_.stop();
        std::cout << "HTTP Server Stop" << std::endl;
    }
}

void HttpServer::addRoute(const std::string& method, const std::string& path, RequestHandler handler) {
    routes_[method][path] = handler;
    std::cout << "Register Route: " << method << " " << path << std::endl;
}

void HttpServer::setDefaultHandler(RequestHandler handler) {
    defaultHandler_ = handler;
}

void HttpServer::doAccept() {
    acceptor_.async_accept(
        [this](beast::error_code ec, tcp::socket socket) {
            if (!ec) {
                auto stream = std::make_shared<beast::tcp_stream>(std::move(socket));
                handleConnection(stream);
            }
            
            if (running_) {
                doAccept();
            }
        });
}

void HttpServer::handleConnection(std::shared_ptr<beast::tcp_stream> stream) {
    auto req = std::make_shared<http::request<http::string_body>>();
    auto res = std::make_shared<http::response<http::string_body>>();
    auto buffer = std::make_shared<beast::flat_buffer>();
    
    // 使用正确的 async_read 重载，包含动态缓冲区
    http::async_read(*stream, *buffer, *req,
        [this, stream, req, res, buffer](beast::error_code ec, std::size_t bytes_transferred) {
            if (!ec) {
                // 记录请求信息
                auto now = std::chrono::system_clock::now();
                auto time_t = std::chrono::system_clock::to_time_t(now);
                std::cout << std::put_time(std::localtime(&time_t), "%Y-%m-%d %H:%M:%S")
                          << " " << req->method_string() << " " << req->target() << std::endl;
                
                handleRequest(*req, *res);
                sendResponse(stream, *res);
            }
        });
}

void HttpServer::handleRequest(http::request<http::string_body>& req, http::response<http::string_body>& res) {
    // 设置默认响应头
    res.version(req.version());
    res.keep_alive(req.keep_alive());
    res.set(http::field::server, "Boost HTTP Server");
    res.set(http::field::content_type, "text/html; charset=utf-8");
    // 查找路由处理器
    auto method_it = routes_.find(std::string(req.method_string()));
    getGlobalLog()->LogDebug(std::string(req.method_string()));
    if (method_it != routes_.end()) {
        getGlobalLog()->LogDebug(std::string(req.target()));
        for (auto item: method_it->second) {
            getGlobalLog()->LogDebug(item.first);
        }
        auto path_it = method_it->second.find(std::string(req.target()));
        if (path_it != method_it->second.end()) {
            // 找到匹配的路由，调用处理器
            path_it->second(req, res);
            return;
        }
    }
    // 没有找到匹配的路由，使用默认处理器
    defaultHandler_(req, res);
}

void HttpServer::sendResponse(std::shared_ptr<beast::tcp_stream> stream, http::response<http::string_body>& res) {
    auto keep_alive = res.keep_alive();
    http::async_write(*stream, res,
        [this, stream, keep_alive](beast::error_code ec, std::size_t bytes_transferred) {
            if (!ec && keep_alive) {
                // 保持连接，处理下一个请求
                handleConnection(stream);
            }
        });
}

void HttpServer::defaultRequestHandler(http::request<http::string_body>& req, http::response<http::string_body>& res) {
    res.result(http::status::not_found);
    res.body() = R"(
<!DOCTYPE html>
<html>
<head>
    <title>404 - 页面未找到</title>
    <meta charset="utf-8">
    <style>
        body { font-family: Arial, sans-serif; text-align: center; margin-top: 50px; }
        h1 { color: #333; }
        p { color: #666; }
    </style>
</head>
<body>
    <h1>404 - 页面未找到</h1>
    <p>请求的页面 ")" + std::string(req.target()) + R"(" 不存在。</p>
    <p><a href="/">返回首页</a></p>
</body>
</html>
    )";
    res.prepare_payload();
}

void HttpServer::onGetTest(http::request<http::string_body>& req, http::response<http::string_body>& res) {
    getGlobalLog()->LogDebug("Receive HTTP Header");
    for (auto const& field : req) {
       getGlobalLog()->LogInfo(std::format("key:{}----v:{}", std::string(field.name_string()), std::string(field.value())));
    }
    res.result(http::status::ok);
    res.body() = R"(you requested GET /test)";
    res.prepare_payload();
}